package com.njtoyo.taxi.admin.service.business.impl;

import cn.hutool.core.util.ObjectUtil;
import com.baomidou.dynamic.datasource.annotation.DS;
import com.baomidou.dynamic.datasource.annotation.DSTransactional;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.conditions.update.LambdaUpdateChainWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.njtoyo.taxi.admin.cache.PrimaryCachePutter;
import com.njtoyo.taxi.admin.handler.FilterHandler;
import com.njtoyo.taxi.admin.library.Const;
import com.njtoyo.taxi.admin.library.common.OperationRecordHelper;
import com.njtoyo.taxi.admin.library.common.util.TimeUtil;
import com.njtoyo.taxi.admin.mapper.master.entity.Company;
import com.njtoyo.taxi.admin.mapper.master.entity.CompanyFeeRate;
import com.njtoyo.taxi.admin.mapper.master.entity.GeoCanton;
import com.njtoyo.taxi.admin.mapper.master.mapper.CompanyFeeRateMapper;
import com.njtoyo.taxi.admin.mapper.master.mapper.CompanyMapper;
import com.njtoyo.taxi.admin.mapper.master.mapper.GeoCantonMapper;
import com.njtoyo.taxi.admin.rest.presenter.business.CompanyFeeRatePresenter;
import com.njtoyo.taxi.admin.rest.presenter.business.CompanyListPresenter;
import com.njtoyo.taxi.admin.rest.presenter.platfrom.AdminUserIdentityPresenter;
import com.njtoyo.taxi.admin.rest.wrapper.business.company.*;
import com.njtoyo.taxi.admin.service.business.CompanyService;
import com.njtoyo.taxi.entity.backend.AdminUser;
import com.njtoyo.taxi.entity.backend.Enum;
import com.taxi.entity.common.RestResult;
import com.taxi.entity.common.ResultEnum;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.util.ObjectUtils;

import java.math.BigDecimal;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Objects;

import static java.util.stream.Collectors.toList;


@Component
@DS(Const.PRIMARY_DS)
public class CompanyServiceImpl implements CompanyService {

    @Autowired
    private CompanyMapper companyMapper;

    @Autowired
    private GeoCantonMapper geoCantonMapper;

    @Autowired
    private OperationRecordHelper operationRecordHelper;

    @Autowired
    private CompanyFeeRateMapper companyFeeRateMapper;

    @Autowired
    private PrimaryCachePutter primaryCachePutter;


    @Override
    public RestResult getAll(AdminUser adminUser, CompanyQueryWrapper wrapper) {

        FilterHandler filterHandler = new FilterHandler(adminUser, wrapper.getCantonId(), null);
        QueryWrapper<Company> queryWrapper = new QueryWrapper<>();

        switch (filterHandler.getFilterType()) {
            case canton:
                queryWrapper.in("canton_id", filterHandler.getCantonIds());
                break;
            case company:
                queryWrapper.in("id", filterHandler.getCompanyIds());
                break;
        }
        queryWrapper.select("id, name")
                .eq(Objects.nonNull(wrapper.getDriverRegionId()), "driver_region_id", wrapper.getDriverRegionId());
        List<Company> res = companyMapper.selectList(queryWrapper);

        return RestResult.success(res);
    }

    /**
     * 公司列表查询
     *
     * @param adminUser
     * @param wrapper
     * @return
     */
    @Override
    public RestResult<Page<CompanyListPresenter>> companies(AdminUser adminUser, CompanyListWrapper wrapper) {
        AdminUserIdentityPresenter identity = (AdminUserIdentityPresenter) adminUser.getIdentity();
        if (!adminUser.getAccountType().equals(Enum.AccountType.platform)) {
            switch (adminUser.getAccountType()) {
                case canton:
                    wrapper.setCantonIds(identity.getCantonIds());
                    break;
                case company:
                    wrapper.setCompanyIds(identity.getCompanyIds());
                    break;
            }
        }
        Page<CompanyListPresenter> companyListPresenters = companyMapper.selectCompanyList(wrapper);
        List<Long> contonIds = companyListPresenters.getRecords().stream()
                .map(CompanyListPresenter::getContonId)
                .collect(toList());
        if (contonIds.size() == 0) {
            return RestResult.success(companyListPresenters);
        }
        //行政区ID
        QueryWrapper<GeoCanton> geoCantonQueryWrapper = new QueryWrapper<>();
        geoCantonQueryWrapper.select("id", "name");
        geoCantonQueryWrapper.in("id", contonIds);
        List<GeoCanton> geoCantons = geoCantonMapper.selectList(geoCantonQueryWrapper);
        for (CompanyListPresenter c : companyListPresenters.getRecords()) {
            Long contonId = c.getContonId();
            for (GeoCanton g : geoCantons) {
                if (contonId.equals(g.getId())) {
                    c.setCantonName(g.getName());
                }
            }
        }
        return RestResult.success(companyListPresenters);
    }

    /**
     * 新增公司
     *
     * @param wrapper
     * @return
     */
    @Override
    public RestResult addCompany(CompanyAddWrtapper wrapper) {
        Company checkCompany = companyMapper.selectOne(Wrappers.<Company>lambdaQuery().eq(Company::getName, wrapper.getName()));
        if (ObjectUtil.isNotNull(checkCompany)) {
            return RestResult.failed("添加失败,公司名称已存在");

        }
        Company company = new Company();
        BeanUtils.copyProperties(wrapper, company);
        companyMapper.insert(company);
        Long id = company.getId();
        operationRecordHelper.addBusinessLog(String.format("新增了公司 [%d] 的信息", id));
        return RestResult.success();
    }

    /**
     * 修改公司基本信息
     *
     * @param id
     * @param wrapper
     * @return
     */
    @Override
    public RestResult updateCompanyBasic(Long id, CompanyUpdateWrapper wrapper) {
        Company company = companyMapper.selectById(id);
        if (ObjectUtils.isEmpty(company)) {
            return RestResult.build(ResultEnum.NOT_FOUND);
        }
        new LambdaUpdateChainWrapper<>(companyMapper)
                .eq(Company::getId, id)
                .set(Company::getName, wrapper.getName())
                .set(Company::getFullName, wrapper.getFullName())
                .set(Company::getAddress, wrapper.getAddress())
                .set(Company::getPersonInCharge, wrapper.getPersonInCharge())
                .set(Company::getContactNumber, wrapper.getContactNumber())
                .update();
        operationRecordHelper.addBusinessLog(String.format("修改了公司 [%d] 的基本信息", id));
        return RestResult.success();
    }

    /**
     * 公司手续费
     *
     * @param companyId
     * @return
     */
    @Override
    public RestResult<List<CompanyFeeRatePresenter>> companyFreeRateList(Long companyId) {
        Company company = companyMapper.selectById(companyId);
        if (ObjectUtils.isEmpty(company)) {
            return RestResult.build(ResultEnum.NOT_FOUND);
        }
        //公司手续费
        QueryWrapper<CompanyFeeRate> companyFeeRateQuery = new QueryWrapper<>();
        companyFeeRateQuery.select("id", "company_id", "driver_earning_ratio", "company_earning_ratio", "max_fee", "start_timestamp", "end_timestamp", "created_at", "updated_at");
        companyFeeRateQuery.in("company_id", companyId);
        List<CompanyFeeRate> list
                = companyFeeRateMapper.selectList(companyFeeRateQuery);
        List<CompanyFeeRatePresenter> companyFeeRates = null;
        if (CollectionUtils.isNotEmpty(list)) {
            companyFeeRates = list.stream().map(c -> {
                CompanyFeeRatePresenter companyFeeRate = new CompanyFeeRatePresenter();
                Integer maxFee = c.getMaxFee();
                if (maxFee != null) {
                    companyFeeRate.setMaxFee(BigDecimal.valueOf(maxFee).movePointLeft(2));
                }
                BeanUtils.copyProperties(c, companyFeeRate);
                return companyFeeRate;
            }).collect(toList());
        }
        return RestResult.success(companyFeeRates);
    }

    /**
     * 公司手续费修改
     *
     * @param companyId
     * @param wrapper
     * @return
     */
    @Override
    @DSTransactional
    public RestResult companFreeRateupdate(Long companyId, CompanFreeRateWrapper wrapper) {
        Company company = companyMapper.selectById(companyId);
        if (ObjectUtils.isEmpty(company)) {
            return RestResult.build(ResultEnum.NOT_FOUND);
        }
        List<CompanFreeRateWrapper.CompanyFeeRates> companyFeeRates = wrapper.getCompanyFeeRates();
        //同一个公司下，日期不能重叠
        List<String> list = new ArrayList<>();
        for (CompanFreeRateWrapper.CompanyFeeRates c : companyFeeRates) {
            String startTimestamp = c.getStartTimestamp();
            String endTimestamp = c.getEndTimestamp();
            list.add(startTimestamp + "--" + endTimestamp);
        }
        try {
            TimeUtil.timeOverlap(list);
        } catch (Exception e) {
            return RestResult.failed(e.getMessage());
        }

        //入库时间改变
        SimpleDateFormat simpleDateFormat
                = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        List<CompanyFeeRate> companyFeeRateList = new ArrayList<>();
        for (CompanFreeRateWrapper.CompanyFeeRates c : companyFeeRates) {
            CompanyFeeRate companyFeeRate = new CompanyFeeRate();
            companyFeeRate.setCompanyId(companyId);
            //接口的结束时间，加上 23:59:59
            String start = c.getStartTimestamp();
            String end = c.getEndTimestamp();
            String startTime = start + " 00:00:00";
            String endTime = end + " 23:59:59";
            try {
                Integer startTimestamp = (int) (simpleDateFormat.parse(startTime).getTime() / 1000);
                if (end != null) {
                    Integer endTimestamp = (int) (simpleDateFormat.parse(endTime).getTime() / 1000);
                    companyFeeRate.setEndTimestamp(endTimestamp);
                }
                companyFeeRate.setStartTimestamp(startTimestamp);

            } catch (ParseException e) {
                e.printStackTrace();
            }
            //司机分成比为0,公司,平台也没有分成
            Integer driverEarningRatio = c.getDriverEarningRatio();
            Integer companyEarningRatio = c.getCompanyEarningRatio();
            if (driverEarningRatio <= 0) {
                c.setCompanyEarningRatio(0);
            }
            //分成比不能超过100%
            if (driverEarningRatio + companyEarningRatio > 1000) {
                return RestResult.failed("司机分成比和公司分成比总比不能超过100%");
            }
            //司机可得分成比
            companyFeeRate.setDriverEarningRatio(c.getDriverEarningRatio());
            //公司可得分成比
            companyFeeRate.setCompanyEarningRatio(c.getCompanyEarningRatio());
            //最高收取的手续费单位由 元 转换成 分
            if (c.getMaxFee() != null) {
                BigDecimal maxFee = c.getMaxFee().movePointRight(2);
                companyFeeRate.setMaxFee(maxFee.intValue());
            }
            companyFeeRateList.add(companyFeeRate);
        }

        //直接删除所有的手续费配置
        QueryWrapper<CompanyFeeRate> companyFeeRateQuery = new QueryWrapper<>();
        companyFeeRateQuery.in("company_id", companyId);
        List<CompanyFeeRate> companyFeeRate1 = companyFeeRateMapper.selectList(companyFeeRateQuery);
        companyFeeRateMapper.delete(companyFeeRateQuery);
        //
        if (ObjectUtils.isEmpty(companyFeeRates)) {
            operationRecordHelper.addBusinessLog(String.format("清空了公司 [%d] 的手续费信息,原来的配置信息 %s", companyId, companyFeeRate1));
            primaryCachePutter.deleteCompanyFeeRateById();
            return RestResult.success();
        }
        for (CompanyFeeRate companyFeeRate : companyFeeRateList) {
            companyFeeRateMapper.insert(companyFeeRate);
        }
        operationRecordHelper.addBusinessLog(String.format("修改了公司 [%d] 的手续费信息,原来的配置信息 %s", companyId, companyFeeRate1));
        primaryCachePutter.deleteCompanyFeeRateById();
        return RestResult.success();
    }

    @Override
    public RestResult infoServiceById(Integer current, Integer size, Integer companyId,String selectStartDate,String selectEndDate) {
        Page page = new Page(current, size);
        Page<Map<String, Object>> pages = companyMapper.selectInfoServiceById(page, companyId, selectStartDate,selectEndDate);
        return RestResult.success(pages);
    }
}
